<template>
  <div class="parameter-pass-container">
    <h1 class="text-3xl font-bold text-center mb-8">Vue3 父子组件通讯演示</h1>

    <!-- 单向数据流说明 -->
    <div class="bg-blue-50 border-l-4 border-blue-500 p-6 mb-8 rounded-lg">
      <h2 class="text-xl font-semibold mb-4 text-blue-800">🔄 Vue 单向数据流原则</h2>
      <div class="text-blue-700 space-y-2">
        <p>• <strong>数据向下流动</strong>：父组件通过 props 向子组件传递数据</p>
        <p>• <strong>事件向上传递</strong>：子组件通过 emit 向父组件发送事件</p>
        <p>• <strong>禁止直接修改 props</strong>：子组件不能直接修改从父组件接收的数据</p>
        <p>• <strong>保持数据可预测</strong>：数据的修改只能在数据的所有者组件中进行</p>
      </div>
    </div>

    <!-- 演示区域 -->
    <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
      <!-- 1. Props 通讯演示 -->
      <div class="demo-section">
        <h3 class="demo-title">1. Props 通讯 (父→子)</h3>
        <div class="demo-content">
          <div class="mb-4">
            <label class="block text-sm font-medium mb-2">父组件数据:</label>
            <input
              v-model="parentMessage"
              class="w-full p-2 border rounded-md"
              placeholder="修改这里会传递给子组件"
            />
            <div class="mt-2">
              <label class="inline-flex items-center">
                <input v-model="isActive" type="checkbox" class="mr-2" />
                激活状态
              </label>
            </div>
          </div>

          <PropsChild
            :message="parentMessage"
            :count="parentCount"
            :is-active="isActive"
            :user-info="userInfo"
            @update-count="handleCountUpdate"
          />
        </div>
      </div>

      <!-- 2. Emit 通讯演示 -->
      <div class="demo-section">
        <h3 class="demo-title">2. Emit 通讯 (子→父)</h3>
        <div class="demo-content">
          <div class="mb-4">
            <p class="text-sm text-gray-600 mb-2">子组件发送的消息:</p>
            <div class="bg-gray-100 p-3 rounded-md min-h-[100px]">
              <div v-for="(msg, index) in receivedMessages" :key="index" class="mb-1">
                <span class="text-xs text-gray-500">{{ msg.time }}</span>
                <span class="ml-2">{{ msg.content }}</span>
              </div>
            </div>
          </div>

          <EmitChild @send-message="handleMessage" @custom-event="handleCustomEvent" />
        </div>
      </div>

      <!-- 3. v-model 双向绑定演示 -->
      <div class="demo-section">
        <h3 class="demo-title">3. v-model 双向绑定</h3>
        <div class="demo-content">
          <div class="mb-4">
            <p class="text-sm font-medium mb-2">父组件的值: {{ formData.username }}</p>
            <p class="text-sm font-medium mb-2">父组件的邮箱: {{ formData.email }}</p>
          </div>

          <VModelChild v-model:username="formData.username" v-model:email="formData.email" />
        </div>
      </div>

      <!-- 4. Provide/Inject 演示 -->
      <div class="demo-section">
        <h3 class="demo-title">4. Provide/Inject 跨级通讯</h3>
        <div class="demo-content">
          <div class="mb-4">
            <label class="block text-sm font-medium mb-2">主题设置:</label>
            <select v-model="theme" class="w-full p-2 border rounded-md">
              <option value="light">浅色主题</option>
              <option value="dark">深色主题</option>
              <option value="blue">蓝色主题</option>
            </select>
          </div>

          <ProvideParent />
        </div>
      </div>

      <!-- 5. Template Refs 和 Expose 演示 -->
      <div class="demo-section">
        <h3 class="demo-title">5. Template Refs & Expose</h3>
        <div class="demo-content">
          <div class="mb-4 space-x-2">
            <button @click="callChildMethod" class="btn-primary">调用子组件方法</button>
            <button @click="getChildData" class="btn-secondary">获取子组件数据</button>
          </div>

          <div v-if="childData" class="mb-4 p-3 bg-green-50 rounded-md">
            <p class="text-green-800">子组件内部数据: {{ childData }}</p>
          </div>

          <ExposeChild ref="exposeChildRef" />
        </div>
      </div>

      <!-- 6. 状态管理演示 -->
      <div class="demo-section">
        <h3 class="demo-title">6. 状态管理 (Pinia Store)</h3>
        <div class="demo-content">
          <div class="mb-4">
            <p class="text-sm font-medium mb-2">全局计数器: {{ globalCount }}</p>
            <div class="space-x-2">
              <button @click="incrementGlobal" class="btn-primary">全局 +1</button>
              <button @click="decrementGlobal" class="btn-secondary">全局 -1</button>
              <button @click="resetGlobal" class="btn-danger">重置</button>
            </div>
          </div>

          <StoreChild />
        </div>
      </div>
    </div>

    <!-- 最佳实践提示 -->
    <div class="mt-12 bg-green-50 border-l-4 border-green-500 p-6 rounded-lg">
      <h2 class="text-xl font-semibold mb-4 text-green-800">✅ 最佳实践建议</h2>
      <div class="text-green-700 space-y-2">
        <p>• <strong>Props 验证</strong>：始终为 props 定义类型和验证规则</p>
        <p>• <strong>事件命名</strong>：使用 kebab-case 命名自定义事件</p>
        <p>
          • <strong>避免深层传递</strong>：超过 3 层的组件通讯考虑使用 provide/inject 或状态管理
        </p>
        <p>• <strong>单一职责</strong>：每个组件只负责自己的数据和行为</p>
        <p>• <strong>可预测性</strong>：数据流向要清晰，避免双向绑定滥用</p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, provide } from 'vue'
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'

// 导入子组件
import PropsChild from './components/PropsChild.vue'
import EmitChild from './components/EmitChild.vue'
import VModelChild from './components/VModelChild.vue'
import ProvideParent from './components/ProvideParent.vue'
import ExposeChild from './components/ExposeChild.vue'
import StoreChild from './components/StoreChild.vue'

// 1. Props 相关数据
const parentMessage = ref('Hello from Parent!')
const parentCount = ref(0)
const isActive = ref(true)
const userInfo = reactive({
  name: 'Vue3 开发者',
  age: 25,
  skills: ['Vue', 'TypeScript', 'Vite'],
})

// Props 数据更新处理
const handleCountUpdate = (newCount: number) => {
  parentCount.value = newCount
}

// 2. Emit 相关数据
interface ReceivedMessage {
  time: string
  content: string
}

const receivedMessages = ref<ReceivedMessage[]>([])

const handleMessage = (message: string) => {
  receivedMessages.value.push({
    time: new Date().toLocaleTimeString(),
    content: `收到消息: ${message}`,
  })
}

const handleCustomEvent = (data: any) => {
  receivedMessages.value.push({
    time: new Date().toLocaleTimeString(),
    content: `自定义事件: ${JSON.stringify(data)}`,
  })
}

// 3. v-model 相关数据
const formData = reactive({
  username: 'admin',
  email: 'admin@example.com',
})

// 4. Provide/Inject 相关
const theme = ref('light')

// 提供主题给子组件
provide('theme', theme)
provide('updateTheme', (newTheme: string) => {
  theme.value = newTheme
})

// 5. Template Refs 相关
const exposeChildRef = ref()
const childData = ref('')

const callChildMethod = () => {
  if (exposeChildRef.value) {
    exposeChildRef.value.childMethod('来自父组件的调用')
  }
}

const getChildData = () => {
  if (exposeChildRef.value) {
    childData.value = exposeChildRef.value.getChildData()
  }
}

// 6. 状态管理相关
const counterStore = useCounterStore()
const { count: globalCount } = storeToRefs(counterStore)

const incrementGlobal = () => counterStore.increment()
const decrementGlobal = () => counterStore.decrement()
const resetGlobal = () => counterStore.reset()
</script>

<style scoped lang="scss">
.parameter-pass-container {
  @apply max-w-7xl mx-auto p-6;
}

.demo-section {
  @apply bg-white rounded-lg shadow-md overflow-hidden;
}

.demo-title {
  @apply text-lg font-semibold p-4 bg-gray-50 border-b;
}

.demo-content {
  @apply p-4;
}

.btn-primary {
  @apply px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors;
}

.btn-secondary {
  @apply px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 transition-colors;
}

.btn-danger {
  @apply px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 transition-colors;
}
</style>
